#include "proxyfactory.h"
#include <QNetworkReply>
#include <QVariant>

ProxyFactory::ProxyFactory()
{
    working.append(new ProxyDesc(QNetworkProxy::NoProxy));
    working.first()->setStatus(ProxyDesc::WORKING);
    pending.append(new ProxyDesc(QNetworkProxy::Socks5Proxy, "localhost", 1234));
    pending.append(new ProxyDesc(QNetworkProxy::Socks5Proxy, "localhost", 1235));
    pending.append(new ProxyDesc(QNetworkProxy::Socks5Proxy, "localhost", 1236));
    pending.append(new ProxyDesc(QNetworkProxy::Socks5Proxy, "localhost", 1237));
    testPending();
    connect(&testSocket,SIGNAL(finished(QNetworkReply*)),
            this, SLOT(socketResponse(QNetworkReply*)));

    proxyTimer.setInterval(30000);
    connect(&proxyTimer,SIGNAL(timeout()),
            this, SLOT(timerRing()));
    proxyTimer.start();

}

ProxyDesc* ProxyFactory::getProxy(){
    //TODO
    if(!working.isEmpty()){
        inUse.append(working.first());
        return working.takeFirst();
    }else{
        return NULL;
    }
};

ProxyDesc* ProxyFactory::getProxyFor(QString hostService){
    for(int i=0; i<working.size(); i++){
        if(working.at(i)->canDownload(hostService)){
            inUse.append(working.at(i));
            return working.takeAt(i);
        }
    }
    return NULL;
};

void ProxyFactory::returnProxy(ProxyDesc* proxy){
    inUse.removeAll(proxy);
    pending+=proxy;
};

void ProxyFactory::timerRing(){
    pending+=working;
    working.clear();
    pending+=notWorking;
    notWorking.clear();
    if(!pending.isEmpty()){
        testPending();
    }
};

void ProxyFactory::testPending(){
    if(pending.isEmpty())return;
    QNetworkProxy* proxy=pending.first();
    testSocket.setProxy(*proxy);
    testSocket.get(QNetworkRequest(QUrl("http://www.blank.org")));
};

void ProxyFactory::socketResponse(QNetworkReply*rsp){
    if(pending.isEmpty()){
        return;
    }
    //qDebug()<<rsp->readAll();
    if(rsp->error()==0){
        //qDebug()<<"working"<<QString().number(pending.first()->port());
        pending.first()->setStatus(ProxyDesc::WORKING);
        working+=pending.takeFirst();
    }else{
        //qDebug()<<"NOTworking"<<QString().number(pending.first()->port());
        pending.first()->setStatus(ProxyDesc::NOTWORKING);
        notWorking+=pending.takeFirst();
    }
    if(!pending.isEmpty()){
        testPending();
    }
};

ProxyFactory::~ProxyFactory(){
    while(!working.isEmpty()){
        delete working.takeFirst();
    }
    while(!notWorking.isEmpty()){
        delete notWorking.takeFirst();
    }
    while(!pending.isEmpty()){
        delete pending.takeFirst();
    }
}


QVector<ProxyDesc*> ProxyFactory::getUpdProxies(){
    QVector<ProxyDesc*> out;
    for(int i=0; i<working.size(); i++){
        if(working.at(i)->changed)out.append(working.at(i));
    }
    for(int i=0; i<notWorking.size(); i++){
        if(working.at(i)->changed)out.append(notWorking.at(i));
    }
    for(int i=0; i<pending.size(); i++){
        if(working.at(i)->changed)out.append(pending.at(i));
    }
    for(int i=0; i<inUse.size(); i++){
        if(working.at(i)->changed)out.append(inUse.at(i));
    }
    return out;
};

QVector<ProxyDesc*> ProxyFactory::getAllProxies(){
    QVector<ProxyDesc*> out;
    for(int i=0; i<working.size(); i++){
        out.append(working.at(i));
    }
    for(int i=0; i<notWorking.size(); i++){
        out.append(notWorking.at(i));
    }
    for(int i=0; i<pending.size(); i++){
        out.append(pending.at(i));
    }
    for(int i=0; i<inUse.size(); i++){
        out.append(inUse.at(i));
    }
    return out;
};
